package com.zkjd.lingdong.ui.pairing

import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.zkjd.lingdong.bluetooth.BleConstants
import com.zkjd.lingdong.bluetooth.BleManager
import com.zkjd.lingdong.bluetooth.DeviceEvent
import com.zkjd.lingdong.bluetooth.ScanState
import com.zkjd.lingdong.bluetooth.getRssiValue
import com.zkjd.lingdong.model.Device
import com.zkjd.lingdong.repository.DeviceRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import javax.inject.Inject
import timber.log.Timber

/**
 * 配对步骤枚举
 */
enum class PairStep {
    STEP_ONE_CHECK_BLUETOOTH, // 第一步：检查蓝牙权限和开启状态
    STEP_TWO_SCANNING,        // 第二步：扫描并连接设备
    STEP_THREE_PAIRED         // 第三步：配对完成
}

/**
 * 设备配对ViewModel
 */
@HiltViewModel
class PairingViewModel @Inject constructor(
    private val deviceRepository: DeviceRepository,
    private val bleManager: BleManager,
    @ApplicationContext private val context: Context
) : ViewModel() {
    /**
     * 设置超时时间为8秒，比连接超时稍长
     */
    private val CONNECTEDTIMEOUT=30000L
    // 配对步骤
    private val _currentStep = MutableStateFlow(PairStep.STEP_ONE_CHECK_BLUETOOTH)
    val currentStep: StateFlow<PairStep> = _currentStep.asStateFlow()
    
    // 扫描状态
    private val _scanState = MutableStateFlow<ScanState>(ScanState.NotScanning)
    val scanState: StateFlow<ScanState> = _scanState.asStateFlow()
    
    // 蓝牙是否可用
    private val _isBluetoothEnabled = MutableStateFlow(false)
    val isBluetoothEnabled: StateFlow<Boolean> = _isBluetoothEnabled.asStateFlow()
    
    // 当前正在配对的设备
    private val _pairingDevice = MutableStateFlow<BluetoothDevice?>(null)
    val pairingDevice: StateFlow<BluetoothDevice?> = _pairingDevice.asStateFlow()
    
    // 配对是否成功
    private val _isPairingSuccessful = MutableStateFlow(false)
    val isPairingSuccessful: StateFlow<Boolean> = _isPairingSuccessful.asStateFlow()
    
    // UI事件
    private val _uiEvents = MutableSharedFlow<UiEvent>()
    val uiEvents: SharedFlow<UiEvent> = _uiEvents
    
    init {
        //监听连接状态
        viewModelScope.launch {
            deviceRepository.getDeviceEvents()
                .collect { event: com.zkjd.lingdong.repository.DeviceEvent ->
                    when (event) {
                        is com.zkjd.lingdong.repository.DeviceEvent.DeviceConnected -> {
                            if (_pairingDevice.value?.address == event.macAddress && _currentStep.value == PairStep.STEP_TWO_SCANNING) {
                                _currentStep.value = PairStep.STEP_THREE_PAIRED
                                _isPairingSuccessful.value = true
                                _uiEvents.emit(UiEvent.PairingSuccess(event.macAddress))
                            }
                        }

                        else -> {}
                    }
                }
        }
        // 监听扫描状态
        viewModelScope.launch {
            deviceRepository.getScanState().collect { state ->
                _scanState.value = state
                
                when (state) {
                    is ScanState.ScanFailed -> {
                        _uiEvents.emit(UiEvent.ShowError(state.reason))
                    }
                    is ScanState.ScanResult -> {
                        // 只有在第二步才处理扫描结果
                        if (_currentStep.value == PairStep.STEP_TWO_SCANNING) {
                            processDevices(state.devices)
                        }
                    }
                    else -> {}
                }
            }

        }
        
        // 初始检查蓝牙状态
        checkBluetoothStatus()
    }
    
    /**
     * 检查蓝牙状态
     */
    fun checkBluetoothStatus() {
        val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        val bluetoothAdapter = bluetoothManager.adapter
        
        _isBluetoothEnabled.value = bluetoothAdapter?.isEnabled == true
    }
    
    /**
     * 处理扫描到的设备
     */
    private fun processDevices(devices: List<BluetoothDevice>) {
        viewModelScope.launch {
            for (device in devices) {
                // 检查设备是否存在
                val deviceNow=deviceRepository.getDeviceByMacAddress(device.address)
                if (deviceNow==null) {
                    // 不存在的设备，停止扫描并尝试连接
                    stopScan()
                    _pairingDevice.value = device
                    _uiEvents.emit(UiEvent.ShowToast("找到设备: ${device.name}，正在尝试连接..."))
                    
                    connectToDevice(device)
                    break
                }
            }
        }
    }
    
    /**
     * 判断是否为有效的深蓝IOT设备
     */
    private fun isValidDeepAlDevice(device: BluetoothDevice): Boolean {
        val deviceName = device.name ?: return false
        
        // 检查设备名称前缀
        if (!deviceName.startsWith(BleConstants.DEVICE_NAME_HEAD)) {
            return false
        }
        
        // 检查RSSI（信号强度）
        val rssi = device.getRssiValue()
        return rssi >= BleConstants.MIN_RSSI_THRESHOLD
    }
    
    /**
     * 连接到设备并检查服务
     */
    private suspend fun connectToDevice(device: BluetoothDevice) {
        try {
            withContext(Dispatchers.IO) {
                // 尝试连接设备
                val connected = deviceRepository.connectDevice(device)

                if (connected) {
                    // 等待设备完全就绪的事件
                    var deviceReady = false
                    var deviceConnected = false

                    // 设置超时时间为12秒，比连接超时稍长
                    withTimeoutOrNull(CONNECTEDTIMEOUT) {
                        bleManager.getDeviceEvents().collect { event ->
                            when (event) {
                                is DeviceEvent.Connected -> {
                                    if (event.device.address == device.address) {
                                        deviceConnected = true
                                        
                                        // 如果我们只关心连接而不关心就绪状态，可以在此中断
                                        if (!deviceReady) {
                                            Timber.d("设备已连接: ${device.address}，等待就绪状态...")
                                        }
                                    }
                                }
                                is DeviceEvent.DeviceReady -> {
                                    if (event.device.address == device.address) {
                                        deviceReady = true
                                        Timber.d("设备已就绪: ${device.address}，配对完成")
                                        return@collect // 设备已就绪，停止收集事件
                                    }
                                }
                                else -> { /* 忽略其他事件 */ }
                            }
                            
                            // 如果设备已连接且已就绪，停止收集
                            if (deviceConnected && deviceReady) {
                                return@collect
                            }
                        }
                    }

                    // 根据收集到的事件状态决定下一步
                    if (deviceConnected) {
                        // 即使设备没有完全就绪，只要连接成功也认为配对成功
                        _currentStep.value = PairStep.STEP_THREE_PAIRED
                        _isPairingSuccessful.value = true
                        _uiEvents.emit(UiEvent.PairingSuccess(device.address))
                    } else {
                        // 服务验证失败或连接失败
                        _pairingDevice.value = null
                        _uiEvents.emit(UiEvent.PairingFailed("设备连接成功但未验证服务"))
                        startScan() // 重新开启蓝牙扫描模式
                    }
                } else {
                    // 连接失败
                    _pairingDevice.value = null
                    _uiEvents.emit(UiEvent.PairingFailed("连接设备失败"))
                    startScan() // 重新开启蓝牙扫描模式
                }
            }
        } catch (e: Exception) {
            _uiEvents.emit(UiEvent.PairingFailed(e.message ?: "配对过程中发生错误"))
            _pairingDevice.value = null
            // 重新开启蓝牙扫描模式
        }
    }

    /**
     * 把配对完成的设备添加到数据库中
     */
    fun addDeviceToDb(){
        viewModelScope.launch {
            _pairingDevice.value?.let {
                // 如果设备未配对，则进行配对
                //不再配对，好像多个同名设备地址不同配对会产生问题
                if (it.bondState != BluetoothDevice.BOND_BONDED) {
                    it.createBond()
                }
                //添加到数据库中 灵动贴
                val deviceName =
                    "DP" + it.name.substring(BleConstants.DEVICE_NAME_HEAD.length);//Device.generateDefaultName(deviceRepository.getAllDevices().count()+1)
                val d1 = Device(
                    macAddress = it.address,
                    name = deviceName,
                    bleName = it.name
                )
                deviceRepository.addDevice(d1)
            }
        }
    }

    /**
     * 开始配对流程
     */
    fun startPairingProcess() {
        if (_isBluetoothEnabled.value) {
            // 蓝牙已启用，进入第二步
            _currentStep.value = PairStep.STEP_TWO_SCANNING
            startScan()
        } else {
            // 蓝牙未启用，提示用户开启蓝牙
            viewModelScope.launch {
                _uiEvents.emit(UiEvent.RequestBluetoothEnable)
            }
        }
    }
    
    /**
     * 开始扫描
     */
    fun startScan() {
        deviceRepository.startScan()
    }
    
    /**
     * 停止扫描
     */
    fun stopScan() {
        _isBluetoothEnabled.value = false
        deviceRepository.stopScan()
    }
    
    /**
     * 蓝牙已启用的回调
     */
    fun onBluetoothEnabled() {
        _isBluetoothEnabled.value = true
        startPairingProcess()
    }
    
    /**
     * 权限被拒绝的处理
     */
    fun onPermissionDenied() {
        viewModelScope.launch {
            _uiEvents.emit(UiEvent.ShowError("缺少蓝牙权限，无法扫描设备"))
            _scanState.value = ScanState.ScanFailed("缺少蓝牙权限")
        }
    }
    
    /**
     * UI事件
     */
    sealed class UiEvent {
        data class ShowError(val message: String) : UiEvent()
        data class ShowToast(val message: String) : UiEvent()
        data class PairingSuccess(val macAddress: String) : UiEvent()
        data class PairingFailed(val reason: String) : UiEvent()
        object RequestBluetoothEnable : UiEvent()
    }
    
    override fun onCleared() {
        super.onCleared()
        // 确保停止扫描
        deviceRepository.stopScan()
    }
} 